home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-10-28 | 8.1 KB | 348 lines | [TEXT/CWIE] |
- // UAppleEvents © 1996 Nick Beadman
- // Utility class for helping handle the AppleEvent Manager
-
- #include <UAEGizmos.h>
-
- #include "UAppleEvents.h"
-
- AEIdleProcPtr UAppleEvents::sIdleFunc = DefaultAEIdleFunc;
- Boolean UAppleEvents::sRecording = false;
-
- #pragma mark ==== Object Specification ====
-
- OSErr UAppleEvents::GetContainer(const AEDesc& inObjectSpecifier, AEDesc& outContainer)
- {
- OSErr lErr = noErr;
-
- try
- {
- LAESubDesc lSubDesc(inObjectSpecifier);
- lSubDesc = lSubDesc.KeyedItem(keyAEContainer);
- lSubDesc.ToDesc(&outContainer);
- }
- catch(ExceptionCode inErr)
- {
- lErr = inErr;
- }
-
- return lErr;
- }
-
- #pragma mark ==== Sending ====
-
- OSErr UAppleEvents::SendWaitReply(const AppleEvent& inEvent, AppleEvent& outReply, Int32 inTimeout, AESendMode inAdditionalAttr)
- {
- AEIdleUPP lIdleFunc;
- OSErr lErr;
-
- if (sIdleFunc != nil)
- {
- lIdleFunc = NewAEIdleProc(sIdleFunc);
- }
- else
- {
- lIdleFunc = nil;
- }
-
- lErr = ::AESend(&inEvent, &outReply, kAEWaitReply | inAdditionalAttr, kAENormalPriority, inTimeout, lIdleFunc, nil);
-
- if (lIdleFunc != nil)
- {
- DisposeRoutineDescriptor(lIdleFunc);
- }
-
- ExtractOSErr(outReply, lErr);
-
- return lErr;
- }
-
- OSErr UAppleEvents::SendNoReply(const AppleEvent& inEvent, AESendMode inAdditionalAttr)
- {
- OSErr lErr;
- StAEDescriptor lReply;
-
- lErr = ::AESend(&inEvent, lReply, kAENoReply | inAdditionalAttr, kAENormalPriority, kAEDefaultTimeout, nil, nil);
-
- return lErr;
- }
-
- #pragma mark ==== Reply Checking ====
-
- Boolean UAppleEvents::ExtractOSErr(const AppleEvent& inReply, OSErr& outErr)
- {
- LAESubDesc lSubDesc(inReply);
-
- // check for an error number
- LAESubDesc lErrorNumber(lSubDesc.KeyedItem(keyErrorNumber));
- if (lErrorNumber.GetType() != typeNull)
- {
- // attempt to get it as an OSErr
- outErr = lErrorNumber.ToInt16();
- return true;
- }
-
- return false;
- }
-
- Boolean UAppleEvents::ExtractErrorString(const AppleEvent& inReply, StringPtr outString)
- {
- LAESubDesc lSubDesc(inReply);
-
- // look for an error string
- LAESubDesc lErrorString(lSubDesc.KeyedItem(keyErrorString));
- if (lErrorString.GetType() != typeNull)
- {
- // attempt to get it as a pascal string
- lErrorString.ToPString(outString);
- return true;
- }
-
- return false;
- }
-
- #pragma mark ==== User Interaction ====
-
- OSErr UAppleEvents::InteractWithUser(NMRecPtr inNotificationRequest, Int32 inTimeout)
- {
- AEIdleUPP lIdleFunc;
- OSErr lErr;
-
- if (sIdleFunc != nil)
- {
- lIdleFunc = NewAEIdleProc(sIdleFunc);
- }
- else
- {
- lIdleFunc = nil;
- }
-
- lErr = ::AEInteractWithUser(inTimeout, inNotificationRequest, lIdleFunc);
-
- if (lIdleFunc != nil)
- {
- DisposeRoutineDescriptor(lIdleFunc);
- }
-
- return lErr;
- }
-
- #pragma mark ==== Recording ====
-
- OSErr UAppleEvents::InitRecordability(void)
- {
- // install a start and stop recording handler
- OSErr lErr;
-
- lErr = ::AEInstallEventHandler(kCoreEventClass, kAENotifyStartRecording,
- NewAEEventHandlerProc(UAppleEvents::RecordingHandler),
- true, false);
- if (lErr != noErr)
- {
- return lErr;
- }
-
- lErr = ::AEInstallEventHandler(kCoreEventClass, kAENotifyStopRecording,
- NewAEEventHandlerProc(UAppleEvents::RecordingHandler),
- false, false);
-
- return lErr;
- }
-
- OSErr UAppleEvents::Record(const AppleEvent& inAppleEvent)
- {
- if (!sRecording)
- {
- return errAEUnknownSendMode;
- }
-
- OSErr lErr = noErr;
-
- try
- {
- // make a self addressed target
- StAEDescriptor lOurselves;
- ThrowIfOSErr_(UAppleEvents::MakeSelfAddressDesc(lOurselves));
-
- // duplicate the event and change address
- StAEDescriptor lRecordAppleEvent;
- ThrowIfOSErr_(::AEDuplicateDesc(&inAppleEvent, lRecordAppleEvent));
- ThrowIfOSErr_(::AEPutAttributeDesc(lRecordAppleEvent, keyAddressAttr, lOurselves));
-
- // send the apple event, without a reply and no executing
- ThrowIfOSErr_(UAppleEvents::SendNoReply(lRecordAppleEvent, kAEDontExecute));
- }
- catch(ExceptionCode inErr)
- {
- lErr = inErr;
- }
-
- return lErr;
- }
-
- pascal OSErr UAppleEvents::RecordingHandler(const AppleEvent*, AppleEvent*, Int32 inRefCon)
- {
- sRecording = (inRefCon == true);
-
- return noErr;
- }
-
- #pragma mark ==== Self Addressing ====
-
- OSErr UAppleEvents::MakeSelfAddressDesc(AEAddressDesc& outSelfAddressDesc)
- {
- ProcessSerialNumber lCurrentProcess;
-
- lCurrentProcess.highLongOfPSN = 0;
- lCurrentProcess.lowLongOfPSN = kCurrentProcess;
-
- return ::AECreateDesc(typeProcessSerialNumber, (Ptr)&lCurrentProcess,
- sizeof(ProcessSerialNumber), &outSelfAddressDesc);
- }
-
- #pragma mark ==== Comparison ====
-
- Boolean UAppleEvents::EqualTargetIDs(const TargetID& inTargetIDOne, const TargetID& inTargetIDTwo)
- {
- // assume they are different unless all of this is true
- // field by field compare (of name and location)
- if (inTargetIDOne.location.locationKindSelector != inTargetIDTwo.location.locationKindSelector)
- {
- return false;
- }
- // now if it the locationKindSelector is ppcNBPLocation then look at NBPEntry
- if (inTargetIDOne.location.locationKindSelector == ppcNBPLocation)
- {
- // the NBPEntity doesn't appear to be packed
- if (!::EqualString(inTargetIDOne.location.u.nbpEntity.objStr,
- inTargetIDTwo.location.u.nbpEntity.objStr, false, false))
- {
- return false;
- }
- if (!::EqualString(inTargetIDOne.location.u.nbpEntity.zoneStr,
- inTargetIDTwo.location.u.nbpEntity.zoneStr, false, false))
- {
- return false;
- }
- if (!::EqualString(inTargetIDOne.location.u.nbpEntity.typeStr,
- inTargetIDTwo.location.u.nbpEntity.typeStr, false, false))
- {
- return false;
- }
-
- }
- if (!::EqualString(inTargetIDOne.name.name, inTargetIDTwo.name.name, false, false))
- {
- return false;
- }
-
- return true;
- }
-
- // object specifiers need to be of the same class (byID, byName, ...) for this to work
-
- Boolean UAppleEvents::EqualObjectSpecifiers(const AEDesc& inObjectSpecOne, const AEDesc& inObjectSpecTwo)
- {
- // special case the null object
- if (inObjectSpecOne.descriptorType == typeNull || inObjectSpecTwo.descriptorType == typeNull)
- {
- return inObjectSpecOne.descriptorType == inObjectSpecTwo.descriptorType;
- }
-
- LAESubDesc lObjectSpecOne(inObjectSpecOne);
- LAESubDesc lObjectSpecTwo(inObjectSpecTwo);
-
- // compare the object classes (keyAEDesiredClass)
- DescType lObjectClass;
- {
- LAESubDesc lClass = lObjectSpecOne.KeyedItem(keyAEDesiredClass);
- lObjectClass = lClass.ToType();
- }
- DescType lInObjectClass;
- {
- LAESubDesc lClass = lObjectSpecTwo.KeyedItem(keyAEDesiredClass);
- lInObjectClass = lClass.ToType();
- }
- if (lInObjectClass != lObjectClass)
- {
- return false;
- }
-
- // compare the selection data
- StAEDescriptor lData;
- {
- LAESubDesc lKeyData = lObjectSpecOne.KeyedItem(keyAEKeyData);
- lKeyData.ToDesc(&lData.mDesc);
- }
- StAEDescriptor inData;
- {
- LAESubDesc lKeyData = lObjectSpecTwo.KeyedItem(keyAEKeyData);
- lKeyData.ToDesc(&inData.mDesc);
- }
- if (!(UAppleEventsMgr::CompareDescriptors(lData.mDesc, kAEEquals, inData.mDesc)))
- {
- return false;
- }
-
- return true;
- }
-
- #pragma mark ==== Idling ====
-
- void UAppleEvents::SetIdleFunc(AEIdleProcPtr inIdleFunc)
- {
- // Set the idle func. Nil is now NOT ALLOWED - if you specifiy kAEWaitReply, you MUST
- // provide an idle func. To prevent idle processing, set the idle func to NullAEIdleFunc.
-
- ThrowIfNil_(inIdleFunc);
-
- sIdleFunc = inIdleFunc;
- }
-
- pascal Boolean UAppleEvents::DefaultAEIdleFunc(EventRecord* inEvent, long* ioSleepTime, RgnHandle*)
- {
- Boolean lUserCancelled = false;
-
- // first check for command-period in all keyDown events
- EventRecord lKeyEvent;
- while (::GetOSEvent(keyDownMask, &lKeyEvent))
- {
- if (UKeyFilters::IsCmdPeriod(lKeyEvent))
- {
- lUserCancelled = true;
- break;
- }
- }
-
- // now process the event, similar to LApplication::ProcessNextEvent
- // only update,activate, os and null events are documented to come thru here
- // Note: it cannot get at the sleep time, mouse moved region or attachments
- switch(inEvent->what)
- {
- case updateEvt:
- case osEvt:
- case activateEvt:
- {
- LEventDispatcher::GetCurrentEventDispatcher()->DispatchEvent(*inEvent);
- }
- break;
-
- case nullEvent:
- {
- LEventDispatcher::GetCurrentEventDispatcher()->UseIdleTime(*inEvent);
- // set the sleep time
- *ioSleepTime = 12;
- }
- break;
- }
- // periodicals get time after every event
- LPeriodical::DevoteTimeToRepeaters(*inEvent);
-
- return lUserCancelled;
- }
-
- pascal Boolean UAppleEvents::NullAEIdleFunc(EventRecord*, long*, RgnHandle*)
- {
- return false;
- }
-
-